package com.hongyi.system.service.impl;

import com.hongyi.common.framework.constant.Constants;
import com.hongyi.common.framework.constant.UserConstans;
import com.hongyi.common.framework.utils.DateUtils;
import com.hongyi.common.framework.utils.StreamUtils;
import com.hongyi.common.mybatis.domain.BaseEntity;
import com.hongyi.common.saToken.utils.LoginUtils;
import com.hongyi.system.domain.SysNotice;
import com.hongyi.system.domain.SysUser;
import com.hongyi.system.domain.SysUserNotice;
import com.hongyi.system.domain.dto.SysNoticeDto;
import com.hongyi.system.domain.vo.SysNoticeVo;
import com.hongyi.system.domain.vo.SysUserVo;
import com.hongyi.system.mapper.SysNoticeMapper;
import com.hongyi.system.mapper.SysUserMapper;
import com.hongyi.system.mapper.SystemUserNoticeMapper;
import com.hongyi.system.service.ISysNoticeService;
import com.hongyi.websocket.utils.WebSocketUtils;
import org.springframework.stereotype.Service;

import com.hongyi.common.mybatis.page.PageData;
import com.hongyi.common.mybatis.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hongyi.common.framework.utils.string.StringUtils;
import com.hongyi.common.framework.utils.bean.MapstructUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 通知公告Service业务层处理
 *
 * @author DingHao
 * @date 2025-01-24 10:14:00
 */
@Service
public class SysNoticeServiceImpl implements ISysNoticeService {

    @Autowired
    private SysNoticeMapper sysNoticeMapper;

    @Autowired
    private SystemUserNoticeMapper systemUserNoticeMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 构建查询条件
     */
    private LambdaQueryWrapper<SysNotice> buildQueryWrapper(SysNoticeDto dto) {
        Map<String, Object> params = dto.getParams();
        LambdaQueryWrapper<SysNotice> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(dto.getNoticeTitle()), SysNotice::getNoticeTitle, dto.getNoticeTitle());
        lqw.eq(StringUtils.isNotBlank(dto.getNoticeType()), SysNotice::getNoticeType, dto.getNoticeType());
        lqw.eq(StringUtils.isNotBlank(dto.getStatus()), SysNotice::getStatus, dto.getStatus());
        return lqw;
    }

    /**
     * 查询通知公告
     *
     * @param noticeId 通知公告ID
     * @return 通知公告
     */
    @Override
    public SysNoticeVo querySysNoticeVoById(Long noticeId) {
        return sysNoticeMapper.selectVoById(noticeId);
    }

    /**
     * 查询通知公告分页列表
     *
     * @param sysNoticeDto 通知公告业务对象
     * @param pageQuery    分页数据
     * @return 通知公告集合
     */
    @Override
    public PageData<SysNoticeVo> querySysNoticeVoPageList(SysNoticeDto sysNoticeDto, PageQuery pageQuery) {
        LambdaQueryWrapper<SysNotice> lqw = buildQueryWrapper(sysNoticeDto);
        lqw.orderByDesc(BaseEntity::getCreateTime);
        Page<SysNoticeVo> result = sysNoticeMapper.selectVoPage(pageQuery.build(), lqw);
        return PageData.success(result);
    }

    /**
     * 查询通知公告列表
     */
    @Override
    public List<SysNoticeVo> querySysNoticeVoList(SysNoticeDto sysNoticeDto) {
        LambdaQueryWrapper<SysNotice> lqw = buildQueryWrapper(sysNoticeDto);
        return sysNoticeMapper.selectVoList(lqw);
    }

    /**
     * 新增通知公告
     *
     * @param sysNoticeDto 通知公告
     * @return 执行条数
     */
    @Override
    @Transactional
    public int addSysNotice(SysNoticeDto sysNoticeDto) {
        //新增通知公告
        SysNotice sysNotice = MapstructUtils.convert(sysNoticeDto, SysNotice.class);
        sysNoticeMapper.insert(sysNotice);
        Long noticeId = Objects.requireNonNull(sysNotice).getNoticeId();
        //根据通知用户标识新增用户与通知公告关联,并用websocket推送
        if (sysNoticeDto.getUserIcon().equals(UserConstans.PARTIAL_USERS)) {
            List<Long> userIds = sysNoticeDto.getUserIds();
            buildUserNoticeList(userIds, noticeId);
            userIds.stream().parallel().forEach(userId -> {
                WebSocketUtils.sendMessage(userId, "您有新的通知公告，请及时查看！");
            });
        } else {
            List<SysUserVo> sysUserVos = sysUserMapper.selectVoList(new LambdaQueryWrapper<SysUser>()
                    .eq(SysUser::getStatus,UserConstans.NORMAL));
            List<Long> userIds = StreamUtils.toList(sysUserVos, SysUserVo::getUserId);
            buildUserNoticeList(userIds, noticeId);
            WebSocketUtils.publishAll("您有新的通知公告，请及时查看！");
        }
        return 1;
    }

    /**
     * 新增用户与通知公告关联
     *
     * @param userIds 用户ID集合
     * @param noticeId 通知公告ID
     */
    private void buildUserNoticeList(List<Long> userIds,Long noticeId ){
        List<SysUserNotice> userNoticeList = StreamUtils.toList(userIds, userId -> {
            SysUserNotice systemUserNotice = new SysUserNotice();
            systemUserNotice.setNoticeId(noticeId);
            systemUserNotice.setUserId(userId);
            systemUserNotice.setReadStatus(Constants.UN_READ);
            systemUserNotice.setReadTime(DateUtils.getNowDate());
            return systemUserNotice;
        });
        systemUserNoticeMapper.insertBatch(userNoticeList);
    }

    /**
     * 修改通知公告
     *
     * @param sysNoticeDto 通知公告
     * @return 执行条数
     */
    @Override
    public int editSysNotice(SysNoticeDto sysNoticeDto) {
        SysNotice sysNotice = MapstructUtils.convert(sysNoticeDto, SysNotice.class);
        return sysNoticeMapper.updateById(sysNotice);
    }

    /**
     * 批量删除通知公告
     *
     * @param noticeIds 需要删除的通知公告ID
     * @return 执行条数
     */
    @Override
    public int removeSysNoticeByIds(Collection<Long> noticeIds) {
        for (Long noticeId : noticeIds) {
            systemUserNoticeMapper.delete(new LambdaQueryWrapper<SysUserNotice>().eq(SysUserNotice::getNoticeId, noticeId));
        }
        return sysNoticeMapper.deleteBatchIds(noticeIds);
    }


}
